grammar bind;
 options{backtrack=true; memoize=true;} 

@lexer::header {
package org.eclipsecon.dui.dsl.binding.parser;

import org.openarchitectureware.xtext.parser.ErrorMsg;
import org.openarchitectureware.xtext.parser.impl.AntlrUtil;

}

@parser::header {
package org.eclipsecon.dui.dsl.binding.parser;

import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EObject;

import org.openarchitectureware.xtext.parser.impl.AntlrUtil;
import org.openarchitectureware.xtext.XtextFile;
import org.openarchitectureware.xtext.parser.impl.EcoreModelFactory;
import org.openarchitectureware.xtext.parser.ErrorMsg;
import org.openarchitectureware.xtext.parser.model.ParseTreeManagerNeu;
import org.openarchitectureware.xtext.parser.parsetree.Node;

import org.eclipsecon.dui.dsl.binding.MetaModelRegistration;

}
@lexer::members {
	 private List<ErrorMsg> errors = new ArrayList<ErrorMsg>();
	public List<ErrorMsg> getErrors() {
		return errors;
	}

	public String getErrorMessage(RecognitionException e, String[] tokenNames) {
		String msg = super.getErrorMessage(e,tokenNames);
		errors.add(AntlrUtil.create(msg,e,tokenNames));
		return msg;
	}
}

@parser::members {

	private Token getLastToken() {
		return input.LT(-1);
	}

	protected Object convert(Object arg) {
		if (arg instanceof org.antlr.runtime.Token) {
			Token t = (Token) arg;
			String s = t.getText();
			if (t.getType() == bindLexer.RULE_ID && s.startsWith("^")) {
				return s.substring(1);
			} else if (t.getType()==bindLexer.RULE_STRING) {
				return s.substring(1,s.length()-1);
			} else if (t.getType()==bindLexer.RULE_INT) {
				return Integer.valueOf(s);
			}
			return s;
		}
		return arg;
	}


	private EcoreModelFactory factory = new EcoreModelFactory(MetaModelRegistration.getEPackage());
    private ParseTreeManagerNeu ptm = new ParseTreeManagerNeu();
	private XtextFile xtextfile = MetaModelRegistration.getXtextFile();
	
	{
			factory.addImport("", "http://www.eclipse.org/emf/2002/Ecore");
			factory.addImport("db", "platform:/resource/org.eclipsecon.dui.core/model/databinding.ecore");
			factory.addImport("ui", "platform:/resource/org.eclipsecon.dui.core/model/uimodel.ecore");
		
	}

	public ParseTreeManagerNeu getResult() {
		return ptm;
	}

	private List<ErrorMsg> errors = new ArrayList<ErrorMsg>();
	public List<ErrorMsg> getErrors() {
		return errors;
	}

	@Override
	public void reportError(RecognitionException e) {
		String msg = super.getErrorMessage(e,tokenNames);
		errors.add(AntlrUtil.create(msg,e,tokenNames));
		ptm.addError(msg, e);
		// This doesn't work. ANTLR may simply report an superfluous token. In that case,
		// two nodes will be finished instead of one.
		// ptm.ruleFinished(null, end());
	}

    private boolean skipCurrentToken;
    
	@Override
	protected boolean recoverFromMismatchedElement(IntStream arg0, RecognitionException arg1, BitSet arg2) {
		skipCurrentToken = true;
		return super.recoverFromMismatchedElement(arg0, arg1, arg2);
	}
}


parse returns [Node r]:
	 result=ruleDModel
	 // Always return the root node! This prevents that this method is called multiple times
	 // with interesting side effects.
{
if (result != null)
  ptm.setModelElement(result);
$r = ptm.getCurrent();
ptm.ruleFinished(result);}	 EOF
;

ruleDModel returns [EObject result]
@init {boolean hasContent = false;}
:
			{
				$result = factory.create("db", "DModel");
			 }
(({skipCurrentToken = false;}'ui'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}':'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(1)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
 RULE_STRING
{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(2)));
  factory.set($result,"uiModel",convert(temp),false);
  ptm.ruleFinished(temp);
}}
)

({skipCurrentToken = false;}'domain'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(3)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}':'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(4)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
 RULE_STRING
{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(5)));
  factory.set($result,"domainModel",convert(temp),false);
  ptm.ruleFinished(temp);
}}
)

({skipCurrentToken = false;}'->'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(6)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
RULE_ID
{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(7)));
  factory.set($result,"modelRootType",convert(temp),true);
  ptm.ruleFinished(temp);
}}
)

({ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(3)).eContents().get(1)).eContents().get(8)));}temp_DBinding=
ruleDBinding{if (temp_DBinding != null) {
  hasContent = true;
  ptm.setModelElement(temp_DBinding);
  factory.add($result,"bindings",convert(temp_DBinding),false);
  ptm.ruleFinished(temp_DBinding);
} else {
  ptm.destroyNode();
}
}
)*
)
 {if (!hasContent)
  $result = null;};
catch [RecognitionException re] {if (!hasContent)
    $result = null;
reportError(re);
recover(input,re);}

ruleDBinding returns [EObject result]
:
        temp_dcontrolbinding=ruleDControlBinding {$result=temp_dcontrolbinding;}	|        temp_dtemplatebinding=ruleDTemplateBinding {$result=temp_dtemplatebinding;}	;

ruleDControlBinding returns [EObject result]
@init {boolean hasContent = false;}
:
			{
				$result = factory.create("db", "DControlBinding");
			 }
(({skipCurrentToken = false;}'bind'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(7)).eContents().get(1)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
RULE_ID
{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(7)).eContents().get(1)).eContents().get(1)));
  factory.set($result,"control",convert(temp),true);
  ptm.ruleFinished(temp);
}}
)

({skipCurrentToken = false;}'to'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(7)).eContents().get(1)).eContents().get(2)));
  ptm.ruleFinished(getLastToken());
}})

({ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(7)).eContents().get(1)).eContents().get(3)));}temp_PathElement=
rulePathElement{if (temp_PathElement != null) {
  hasContent = true;
  ptm.setModelElement(temp_PathElement);
  factory.set($result,"path",convert(temp_PathElement),false);
  ptm.ruleFinished(temp_PathElement);
} else {
  ptm.destroyNode();
}
}
)

(({skipCurrentToken = false;}'match'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(7)).eContents().get(1)).eContents().get(4)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})

({ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(7)).eContents().get(1)).eContents().get(4)).eContents().get(1)));}temp_Validator=
ruleValidator{if (temp_Validator != null) {
  hasContent = true;
  ptm.setModelElement(temp_Validator);
  factory.set($result,"validator",convert(temp_Validator),false);
  ptm.ruleFinished(temp_Validator);
} else {
  ptm.destroyNode();
}
}
)
)?
)
 {if (!hasContent)
  $result = null;};
catch [RecognitionException re] {if (!hasContent)
    $result = null;
reportError(re);
recover(input,re);}

ruleDTemplateBinding returns [EObject result]
@init {boolean hasContent = false;}
:
			{
				$result = factory.create("db", "DTemplateBinding");
			 }
(({skipCurrentToken = false;}'bind'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}'('{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(1)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
RULE_ID
{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(2)));
  factory.set($result,"template",convert(temp),true);
  ptm.ruleFinished(temp);
}}
)

({skipCurrentToken = false;}')'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(3)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
RULE_ID
{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(4)));
  factory.set($result,"control",convert(temp),true);
  ptm.ruleFinished(temp);
}}
)

({skipCurrentToken = false;}'to'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(5)));
  ptm.ruleFinished(getLastToken());
}})

({ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(6)));}temp_PathElement=
rulePathElement{if (temp_PathElement != null) {
  hasContent = true;
  ptm.setModelElement(temp_PathElement);
  factory.set($result,"path",convert(temp_PathElement),false);
  ptm.ruleFinished(temp_PathElement);
} else {
  ptm.destroyNode();
}
}
)

(({skipCurrentToken = false;}'match'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(7)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})

({ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(8)).eContents().get(1)).eContents().get(7)).eContents().get(1)));}temp_Validator=
ruleValidator{if (temp_Validator != null) {
  hasContent = true;
  ptm.setModelElement(temp_Validator);
  factory.set($result,"validator",convert(temp_Validator),false);
  ptm.ruleFinished(temp_Validator);
} else {
  ptm.destroyNode();
}
}
)
)?
)
 {if (!hasContent)
  $result = null;};
catch [RecognitionException re] {if (!hasContent)
    $result = null;
reportError(re);
recover(input,re);}

rulePathElement returns [EObject result]
@init {boolean hasContent = false;}
:
			{
				$result = factory.create("db", "PathElement");
			 }
(({skipCurrentToken = false;}
RULE_ID
{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(9)).eContents().get(1)).eContents().get(0)));
  factory.set($result,"attribute",convert(temp),true);
  ptm.ruleFinished(temp);
}}
)

(({skipCurrentToken = false;}'.'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(9)).eContents().get(1)).eContents().get(1)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})

({ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(9)).eContents().get(1)).eContents().get(1)).eContents().get(1)));}temp_PathElement=
rulePathElement{if (temp_PathElement != null) {
  hasContent = true;
  ptm.setModelElement(temp_PathElement);
  factory.set($result,"next",convert(temp_PathElement),false);
  ptm.ruleFinished(temp_PathElement);
} else {
  ptm.destroyNode();
}
}
)
)?
)
 {if (!hasContent)
  $result = null;};
catch [RecognitionException re] {if (!hasContent)
    $result = null;
reportError(re);
recover(input,re);}

ruleValidator returns [EObject result]
:
        temp_concretevalidator=ruleConcreteValidator {$result=temp_concretevalidator;}	;

ruleConcreteValidator returns [EObject result]
:
        temp_patternvalidator=rulePatternValidator {$result=temp_patternvalidator;}	;

rulePatternValidator returns [EObject result]
@init {boolean hasContent = false;}
:
			{
				$result = factory.create("db", "PatternValidator");
			 }
(({skipCurrentToken = false;}'pattern'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(12)).eContents().get(1)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
RULE_STRING{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(12)).eContents().get(1)).eContents().get(1)));
  factory.set($result,"pattern",convert(temp),false);
  ptm.ruleFinished(temp);
}}
)

(({skipCurrentToken = false;}'warning'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(12)).eContents().get(1)).eContents().get(2)).eContents().get(0)));
  ptm.ruleFinished(getLastToken());
}})
	|
({skipCurrentToken = false;}
'error'{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)((EObject)xtextfile.eContents().get(12)).eContents().get(1)).eContents().get(2)).eContents().get(1)));
  factory.set($result,"error",true);
  ptm.ruleFinished(temp);
}}
)
)

({skipCurrentToken = false;}':'{if (!skipCurrentToken) {
  hasContent = true;
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(12)).eContents().get(1)).eContents().get(3)));
  ptm.ruleFinished(getLastToken());
}})

({skipCurrentToken = false;}
RULE_STRING{if (!skipCurrentToken) {
  hasContent = true;
  Token temp = getLastToken();
  ptm.createNode(((EObject)((EObject)((EObject)xtextfile.eContents().get(12)).eContents().get(1)).eContents().get(4)));
  factory.set($result,"message",convert(temp),false);
  ptm.ruleFinished(temp);
}}
)
)
 {if (!hasContent)
  $result = null;};
catch [RecognitionException re] {if (!hasContent)
    $result = null;
reportError(re);
recover(input,re);}

RULE_ID :

	 ('^')?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
	 
;

RULE_STRING :

	 '\"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | ~('\\'|'\"') )* '\"' |
	 '\'' ( '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | ~('\\'|'\'') )* '\''
	 
;

RULE_INT :

	 ('-')?('0'..'9')+
	 
;

RULE_WS :

	 (' '|'\t'|'\r'|'\n')+ {$channel=HIDDEN;}
	 
;

RULE_ML_COMMENT :

	 '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
	 
;

RULE_SL_COMMENT :

	 '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
	 
;

